#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Currency Converter Copyright (C) 2009  Chris Marsh
#
# Currency Converter is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or any later version.
#
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# *********************************************************************************
#
# converter_gui.py, This module represents the gui of the conversion widget.
#
# *********************************************************************************

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import qcurrency_rc
from converter import ConversionType,  Converter
from rates_table import RatesTable

# *********************************************************************************

class ConverterGui(QWidget):
    """
    The GUI for QCurrency Converter.
    """
    class EventSource:
        fromSource = 0
        toSource = 1
        
    def __init__(self, autoUpdate=False,  fromIndex = 0,  toIndex = 0,  parent=None):
        super(ConverterGui,self).__init__(parent)
        
        self.__autoUpdate = autoUpdate
        self.__updating = False
        
        typeActionGroup = QActionGroup(self)
        currencyAction = QAction('&Currency',  typeActionGroup)
        currencyAction.setStatusTip('Set conversion to currency')
        currencyAction.setCheckable(True)
        currencyAction.setChecked(True)
        lengthAction = QAction('&Length',  typeActionGroup)
        lengthAction.setStatusTip('Set conversion to length')
        lengthAction.setCheckable(True)
        weightAction = QAction('&Weight',  typeActionGroup)
        weightAction.setStatusTip('Set conversion to weight')
        weightAction.setCheckable(True)
        
        self.updateAction = QAction('&Update',  self)
        self.updateAction.setStatusTip('Update Exchange Rates')
        self.updateAction.setIcon(QIcon(":/update.png"))
        self.connect(self.updateAction, SIGNAL("triggered()"), self.downloadUpdate)
        
        fromLabel = QLabel("Select a currency:")
        self.fromListBox = QComboBox()
        toLabel = QLabel("Select a currency:")
        self.toListBox = QComboBox()
        amountLabel = QLabel("Value:")
        self.fromUnitLabel = QLabel("XXX")
        self.fromSpinBox = QDoubleSpinBox()
        self.fromSpinBox.setRange(0.01, 10000000.00)
        self.fromSpinBox.setValue(1.00)
        self.fromSpinBox.setAlignment(Qt.AlignRight)
        self.toUnitLabel = QLabel("XXX")
        self.toSpinBox = QDoubleSpinBox()
        self.toSpinBox.setRange(0.01, 10000000.00)
        self.toSpinBox.setValue(1.00)
        self.toSpinBox.setAlignment(Qt.AlignRight)
        
        typeMenu = QMenu(self)
        typeMenu.addAction(currencyAction)
        typeMenu.addAction(lengthAction)
        typeMenu.addAction(weightAction)
        convTypeButton = QToolButton()
        convTypeButton.setPopupMode(QToolButton.InstantPopup)
        convTypeButton.setMenu(typeMenu)
        convTypeButton.setIcon(QIcon(":/types.png"))
        
        self.statusLabel = QLabel()
        self.updateButton = QToolButton()
        self.updateButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.updateButton.setDefaultAction(self.updateAction)

        pLayout = QGridLayout()
        pLayout.addWidget(fromLabel, 0, 0)
        pLayout.addWidget(self.fromListBox, 1, 0)
        pLayout.addWidget(self.fromSpinBox, 2, 0)
        pLayout.addWidget(QLabel("="), 2, 1)
        pLayout.addWidget(toLabel, 0, 2)
        pLayout.addWidget(self.toListBox, 1, 2)
        pLayout.addWidget(self.toSpinBox, 2, 2)
        
        mainLayout = QVBoxLayout()
        mainLayout.addLayout(pLayout)
        mainLayout.addStretch()
        
        lowerLayout = QHBoxLayout()
        lowerLayout.addWidget(self.statusLabel)
        lowerLayout.addWidget(self.updateButton)
        lowerLayout.addWidget(convTypeButton)
        
        self.ratesTable = RatesTable()
        currencyLayout = QVBoxLayout()
        currencyLayout.addWidget(self.ratesTable)
        
        tabWidget = QTabWidget()
        mainTab = QWidget()        
        mainTab.setLayout(mainLayout)
        currencyTab = QWidget()
        currencyTab.setLayout(currencyLayout)
        tabWidget.addTab(mainTab,  "Converter")
        tabWidget.addTab(currencyTab,  "Rates")
        
        parentLayout = QVBoxLayout()
        parentLayout.addWidget(tabWidget)
        parentLayout.addLayout(lowerLayout)
        self.setLayout(parentLayout)
        
        self.converter = Converter()
        
        self.connect(self.fromListBox, SIGNAL("currentIndexChanged(int)"), lambda: self.updateResults(self.EventSource.fromSource))
        self.connect(self.toListBox, SIGNAL("currentIndexChanged(int)"), lambda: self.updateResults(self.EventSource.fromSource))
        self.connect(self.fromSpinBox, SIGNAL("valueChanged(double)"),  lambda: self.updateResults(self.EventSource.fromSource))
        self.connect(self.toSpinBox, SIGNAL("valueChanged(double)"), lambda: self.updateResults(self.EventSource.toSource))
        self.connect(currencyAction, SIGNAL("triggered()"), lambda: self.setConversionType(ConversionType.Currency))
        self.connect(lengthAction, SIGNAL("triggered()"), lambda: self.setConversionType(ConversionType.Length))
        self.connect(weightAction, SIGNAL("triggered()"), lambda: self.setConversionType(ConversionType.Weight))
        self.connect(self.converter,  SIGNAL("dataLoaded"),  self.reloadData)
        self.connect(self.converter,  SIGNAL("downloadSuccess"), 
                                                              lambda: QMessageBox.information(None, "Success",
                                                              "Exchange rates successfully updated.",
                                                              QMessageBox.StandardButtons(QMessageBox.Ok),  QMessageBox.Ok))
        self.connect(self.converter,  SIGNAL("downloadFailure"), 
                                                              lambda: QMessageBox.warning(None, "Failed",
                                                              "Failed to download Exchange rates.",
                                                              QMessageBox.StandardButtons(QMessageBox.Ok),  QMessageBox.Ok))
        
        if self.__autoUpdate:
            QTimer.singleShot(0,  self.downloadUpdate)
        
        self.converter.loadData()
        self.setSelections(fromIndex,  toIndex)
    
    def downloadUpdate(self):
        self.converter.downloadCurrency()
    
    def reloadData(self):
        self.statusLabel.setText("Last updated: %s" % self.converter.currencyDate())
        self.updateListItems()
        self.updateRatesTable()
        self.updateResults(self.EventSource.fromSource)
    
    def setConversionType(self,  conversionType):
        self.converter.setConversionType(conversionType)
        self.converter.loadData()
    
    def autoUpdate(self):
        return self.__autoUpdate
    
    def setAutoUpdate(self,  state):
        self.__autoUpdate = state
    
    def setUserColors(self,  mainColor = "#FFFFFF",  altColor = "#333333"):
        styleSheet = "QLabel {font-size: 16px} \
                 QLineEdit {font-size: 16px} \
                 QDoubleSpinBox {font-size: 16px} \
                 QComboBox {font-size: 16px} \
                 QTableWidget {qproperty-alternatingRowColors: True; \
                 background-color:%s; alternate-background-color: %s}" % (mainColor,  altColor)
        self.setStyleSheet(styleSheet)

    def updateListItems(self):
        self.__updating = True
        try:
            self.fromListBox.clear()
            self.toListBox.clear()
            
            for id in self.converter.conversionData:
                iconPath = ":/%s.png" % id
                self.fromListBox.addItem (QIcon(iconPath),  self.converter.conversionData[id][0], QVariant(id))
                self.toListBox.addItem (QIcon(iconPath),  self.converter.conversionData[id][0], QVariant(id))
                
            self.fromListBox.model().sort(0)
            self.toListBox.model().sort(0)
            self.setSelections()
            
        except Exception,  e:
            print e
        finally:
            self.__updating = False

    def updateResults(self, source):
        if self.__updating: return
        try:
            idFrom = "%s" % self.fromListBox.itemData(self.fromListBox.currentIndex()).toString()
            idTo = "%s" % self.toListBox.itemData(self.toListBox.currentIndex()).toString()
            self.fromSpinBox.setSuffix(" %s" % idFrom)
            self.toSpinBox.setSuffix(" %s" % idTo)
            if source == self.EventSource.fromSource:
                amount = self.fromSpinBox.value()
                result = self.converter.convert(amount,  idFrom,  idTo)
                self.toSpinBox.setValue(result)
            else:
                amount = self.toSpinBox.value()
                result = self.converter.convert(amount,  idTo,  idFrom)
                self.fromSpinBox.setValue(result)
        except KeyError:
            # Only partial selection made in list boxes
            pass
    
    def setSelections(self,    fromIndex = 0,  toIndex = 0):
        self.__updating =True
        self.fromListBox.setCurrentIndex(fromIndex)
        self.__updating = False
        self.toListBox.setCurrentIndex(toIndex)

    def updateRatesTable(self):
        idList = self.ratesTable.idList[self.converter.conversionType()][1:]
        self.ratesTable.setRowCount(0)
        self.ratesTable.setHeader(self.converter.conversionType())
        for fromId in idList:
            row = self.ratesTable.rowCount()
            self.ratesTable.insertRow(row)
            rowText = "1 %s =" % fromId
            newCell = QTableWidgetItem(rowText)
            self.ratesTable.setItem(row, 0,  newCell)
            columnCount = 1
            for toId in idList:
                result = self.converter.convert(1,  fromId,  toId)
                cellText = "%0.3f" % result
                newCell = QTableWidgetItem(cellText)
                newCell.setTextAlignment(Qt.AlignCenter|Qt.AlignVCenter)
                newCell.setToolTip("%s %s %s" %  (rowText,  cellText,  toId))
                self.ratesTable.setItem(row, columnCount,  newCell)
                columnCount += 1

# *********************************************************************************

def main():
    import sys
    app = QApplication(sys.argv)
    app.setOrganizationName("qcurrency")
    app.setApplicationName("qcurrency")
    convGui = ConverterGui()
    convGui.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
